package java学习.第08章_面向对象编程_高级;

/**
 * 设计模式：是大量的实践中总结和理论化之后优选的
 *  代码结构、编程风格、以及解决问题的思考方式。
 *  设计模式免去我们自己再思考和摸索。
 *  就像是经典的棋谱，不同的棋局，我们用不同的棋谱。"套路"
 *
 *  经典设计模式有23种
 */
public class B_单例模式和main {

    /**
     * 由于JVM需要调用类的main()方法，所以该方法的访问权限必须是public，
     *      又因为JVM在执行main()方法时不必创建对象，所以该方法必须是static的，
     *      该方法接收一个String类型的数组参数，
     *      该数组中保存执行Java命令时传递给所运行的类的参数。
     *
     * 又因为main() 方法是静态的，我们不能直接访问该类中的非静态成员，
     *      必须创建该类的一个实例对象后，才能通过这个对象去访问类中的非静态成员，
     *      这种情况，我们在之前的例子中多次碰到。
     *
     * javac 方法名.java      //编译
     * java 方法名           //执行
     * java 方法名 1 2 3 5 //后面的就是输入的 args 的值
     *
     */
    public static void main(String[] args) {
        //所有方法的入口  也是程序的入口，格式固定的
        for (int i = 0; i < args.length; i++) {
            System.out.println(args[i]);
        }
    }
}

/**
 * 单例模式
 * 单例设计模式，就是采取一定的方法保证在整个的软件系统中，
 *             对某个类只能存在一个对象实例，
 *             并且该类只提供一个取得其对象实例的方法。
 *
 */
class 饿汉式单例{
    //直接就是线程安全的
    private static 饿汉式单例 d = new 饿汉式单例();
    private 饿汉式单例(){}
    //由于无法调用构造器，所以必须使用静态获取
    public static 饿汉式单例 get饿汉式单例(){
        return d;
    }
}

class 懒汉式单例1{
    private static 懒汉式单例1 d;
    private 懒汉式单例1(){}
    public static 懒汉式单例1 get懒汉式单例1(){
        //但是如果遇到多线程这个方法就不稳了
        if(d == null){ 
            d = new 懒汉式单例1();
        }
        return d;
    }
}
class 懒汉式单例2{
    private static 懒汉式单例2 d;
    private 懒汉式单例2(){}
    //这个 synchronized 锁可以限制一个线程调用
    public synchronized static 懒汉式单例2 get懒汉式单例2(){
        if(d == null){
            d = new 懒汉式单例2();
        }
        return d;
    }
}
class 懒汉式单例3{
    private static 懒汉式单例3 d;
    private 懒汉式单例3(){}
    public static 懒汉式单例3 get懒汉式单例3(){
        if(d == null){
            //这样效率更高
            synchronized (懒汉式单例3.class){
                if(d == null){
                    d = new 懒汉式单例3();
                }
            }
        }
        return d;
    }
}
class 懒汉式单例4{
    private volatile static 懒汉式单例4 d;
    private 懒汉式单例4(){}
    public static 懒汉式单例4 get懒汉式单例4(){
        if(d == null){
            //这样效率更高
            synchronized (懒汉式单例4.class){
                if(d == null){
                    //由于 d = new 懒汉式单例4();这一步在代码底层，分成了好多步
                    //可能会出现d刚刚赋值，但是 new 还没初始化完成，所以会导致
                    //最后的return 是个没要完全的对象 ，
                    // 由于 Java 为了优化，会进行指令重排，这个d可能是个假的d
                    //所以需要给 d加上 volatile 禁止指令重排
                    d = new 懒汉式单例4();
                }
            }
        }
        return d;
    }
}


